home *** CD-ROM | disk | FTP | other *** search
- /* rom2arab.c
-
- David S McMeans Not copyrighted April 1993
- mcmeans@dtedi.hq.aflc.af.mil
-
- Roman2Arabic()
- Converts a Roman number to its Arabic equivalent.
-
- Call
-
- int Roman2Arabic( str )
- char *str; roman number to be converted
-
- Returns
-
- INT
-
- Description
-
- Roman2Arabic() does no error checking. Invalid Roman numerals are ignored.
-
- Notes
-
- Roman2Arabic_() does rudimentary error checking. If the Roman number is
- receives is invalid, it returns 0.
-
- This information was compiled from a discussion in comp.lang.pascal around
- March 1993. Acknowledgements go to Bengt Oehman (d92bo@efd.lth.se), and to
- David Conrad (dave@tygra.michigan.com).
-
- */
-
-
- #include "tailor.h"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
-
- /*
- * PUBLIC DECLARATIONS
- */
-
- typedef enum bool {FALSE, TRUE} Boolean;
- typedef enum ret_t {ERROR=-1, SUCCESS} ReturnType;
-
- extern int Roman2Arabic OF(( char * ));
- extern int Roman2Arabic_ OF(( char * ));
-
- /*
- * PRIVATE DECLARATIONS
- */
-
- static int roman_val OF(( char ));
- static Boolean is_a_five OF(( char ));
-
- /* The following routine was provided by Dave Conrad */
-
- int Roman2Arabic( str )
- char *str;
- {
- int len, i, r, r_ahead, arab;
-
- arab = 0;
- len = strlen( str );
- for (i=0; i < len-1; i++)
- {
- r = roman_val( str[ i ] );
- r_ahead = roman_val( str[ i+1 ] );
- if (r < r_ahead)
- arab -= r;
- else
- arab += r;
- }
- arab += roman_val( str[ len-1 ] );
-
- return arab;
- }
-
- /* The following routine was provided by Bengt Oehman */
-
- int Roman2Arabic_( str )
- char *str;
- {
- int pos;
- int value, curval, highestprev;
-
- highestprev = curval = value = 0;
-
- for (pos=strlen( str )-1; pos>-1; pos--)
- {
- if ((curval = roman_val( str[ pos ] ))==0) /* invalid char in str */
- return 0;
-
- if (curval >= highestprev)
- {
- value += curval;
- highestprev = curval;
- }
- else /* numeral precedes one larger */
- {
- if (is_a_five( str[ pos ] )) /* five may not precede anything larger */
- return 0;
-
- if (highestprev / curval > 10) /* XM IC XD ... */
- return 0;
-
- value -= curval;
- }
- }
- return value;
- }
-
- static int roman_val( n )
- char n;
- {
- switch( toupper( n ) )
- {
- case 'I':
- return 1;
- case 'V':
- return 5;
- case 'X':
- return 10;
- case 'L':
- return 50;
- case 'C':
- return 100;
- case 'D':
- return 500;
- case 'M':
- return 1000;
- default:
- return 0;
- }
- }
-
- static Boolean is_a_five( n )
- char n;
- {
- char c=toupper( n );
-
- return (c=='V' || c=='L' || c=='D');
- }
-
- /* end rom2arab.c */
-